home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
tsr21src.arc
/
DEVICE.PAS
next >
Wrap
Pascal/Delphi Source File
|
1986-07-20
|
7KB
|
200 lines
{
unknown author.
distributed with TSR Utilities Source code for completeness.
}
Program Device_Chain;
type
{===========================================================================
This data type defines the structure of the PC-DOS/MS-DOS File Control
Block and is used by this program to access the pointer to the NUL
device which heads the chain of device driver entries.
Most of the record is illustrated for documentation and completeness.
The actual part that is used to access the device driver chain is listed
in the documentation as "reserved". Note (in the comments below) that
the actual location of this pointer in the FCB is different under versions
2.x and 3.x of the DOS operating system.
}
FileControlBlock =
Record
Drive : Byte;
Filename : Array [1..8] of char;
Extension : Array [1..3] of char;
CurrentBl : Integer;
LRL : Integer;
FilSizeLo : Integer;
FilSizeHi : Integer;
FileDate : Integer;
FileTime : Integer;
{-----------------------------------------------------------------------------
For DOS 3.0 and later, the FCB Structure should be as follows:
remove the alternate braces from the following code segment and
delete the similar code segment which follows it.
}
{----------------------- MS/PC-DOS Version 3.x ---------------------------}
dummy1 : Integer;
DevOffset : Integer;
DevSegment: Integer;
dummy2 : Byte;
dummy3 : Byte;
{----------------------- MS/PC-DOS Version 2.x ---------------------------}
(*
dummy1 : Byte;
DevOffset : Integer;
DevSegment: Integer;
dummy2 : Integer;
dummy3 : Byte;
*)
{-----------------------------------------------------------------------------}
CurRecord : Byte;
RelRecLo : Integer;
RelRecHi : Integer;
End;
{=============================================================================}
DeviceHeader =
Record
NextHeaderOffset : Integer; { Offset address of next device in chain }
NextHeaderSegment: Integer; { Segment address of next device in chain }
Attributes : Integer; { Device attributes }
StrategyEntPt : Integer; { Offset w/i current segment - stragegy }
InterruptEntPt : Integer; { Offset w/i current segment - interrupt }
DeviceName : Array [1..8] of char; { Name of the device }
End;
Registers =
Record
AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Integer;
End;
Str80 = String[80];
var
DeviceControlBlock : FileControlBlock; { File Control Block for NUL Device }
Regs : Registers; { Machine registers for MS-DOS calls}
DevicePtr : ^DeviceHeader; { Pointer to the next device header }
DeviceSegment : integer; { Track the device segment and }
DeviceOffset : integer; { offset while manipulating chain}
{-----------------------------------------------------------------------------
HexStr: Converts the integral value passed by the parameter "number" to a
string of four hexidecimal character digits.
------------------------------------------------------------------------------}
function HexStr ( number : integer ) : Str80;
const
HexChars : Array[0..15] of char = '0123456789ABCDEF';
var
i : Integer;
temp : Str80;
begin { function HexStr }
temp[0] := #4;
for i := 1 to 4 do
begin
temp[5-i] := HexChars[ (number and $000F) ];
number := number shr 4;
end;
HexStr := temp;
end; { function HexStr }
{-----------------------------------------------------------------------------
WritePtr: Takes the two integer paramters and prints them in segment
address format, i.e. SSSS:OOOO
------------------------------------------------------------------------------}
Procedure WritePtr( PtrSeg, PtrOfs : integer );
begin
Write( HexStr(PtrSeg), ':', HexStr(PtrOfs), ' ');
end;
begin { Main program Device_Chain }
LowVideo;
ClrScr;
GotoXY(24,1);
Write('Device Driver');
GotoXY(20,2);
Write('Resident Header Chain');
GotoXY(1,5);
Writeln(' Starting Next Strategy Interrupt Device');
Writeln(' Address Hdr Addr Attr Entry Pnt Entry Pnt Name');
Writeln('--------- --------- ---- --------- --------- --------');
{
Initialize the FCB to zero and set up the NUL device driver name. Then,
attempt to open the device for input. If the open is successful, the
proper device driver pointer addresses are automatically put in the FCB
for our use in the rest of the program.
}
FillChar(DeviceControlBlock,Sizeof(DeviceControlBlock),0);
With DeviceControlBlock do
begin
Filename := 'NUL ';
Extension:= ' ';
With Regs do
begin
AX := $0F00;
DX := Ofs(DeviceControlBlock);
DS := Seg(DeviceControlBlock);
MSDos(Regs);
If (AX and $00FF) <> 0
then
begin
Writeln('Error in opening the NUL Device');
Halt;
end;
end;
DevicePtr := Ptr(DevSegment,DevOffset);
DeviceSegment := DevSegment;
DeviceOffset := DevOffset;
end;
{
Once the proper addresses have bee established, move backward through the
device driver chain, printing the pertinent data as we proceed. The end of
the device driver chain is indicated when the "next device offset" address
is equal to -1 ($FFFF).
}
While DeviceOffset <> $FFFF do
With DevicePtr^ do
begin
WritePtr(DeviceSegment,DeviceOffset);
WritePtr(NextHeaderSegment,NextHeaderOffset);
Write(HexStr(Attributes), ' ');
WritePtr(DeviceSegment,StrategyEntPt);
WritePtr(DeviceSegment,InterruptEntPt);
{
If the device is a character device (the statement below is TRUE),
then the "device name" is a valid 8 character representation. If
the device is a block device (i.e., a disk drive, etc.) then this
field usually contains a number indicating how many devices are
supported by the driver.
}
if (Attributes and $8000) <> 0
then Write(DeviceName)
else Write(Ord(DeviceName[1]),' Block Device Units');
Writeln;
DevicePtr := Ptr(NextHeaderSegment,NextHeaderOffset);
DeviceSegment := NextHeaderSegment;
DeviceOffset := NextHeaderOffset;
end; { With DevicePtr^ }
end. { Device_Chain }